#include "qsql_duckdb_p.h"
#include <QtSql/qsqlquery.h>
#include <QtSql/qsqlrecord.h>
#include <QtSql/qsqlerror.h>
#include <QtSql/qsqlfield.h>
#include <QtSql/qsqlindex.h>
#include <QtCore/qdebug.h>

QT_BEGIN_NAMESPACE

// QDuckdbDriverPrivate 实现
QDuckdbDriverPrivate::QDuckdbDriverPrivate() 
    : QSqlDriverPrivate(), db(nullptr), conn(nullptr), errorMessage(QString()),
      inTransaction(false), isReadOnly(false)
{
}

QDuckdbDriverPrivate::~QDuckdbDriverPrivate()
{
    // 析构函数实现 - 资源清理在 QDuckdbDriver::cleanup() 中处理
}

void QDuckdbDriverPrivate::handleError(const char *error)
{
    if (error) {
        errorMessage = QString::fromUtf8(error);
    } else {
        errorMessage = QStringLiteral("Unknown error");
    }
}

void QDuckdbDriverPrivate::splitSchemaTableName(const QString &name, QString &schema, QString &table)
{
    const int dotPos = name.lastIndexOf(QLatin1Char('.'));
    if (dotPos != -1) {
        schema = name.left(dotPos);
        table = name.mid(dotPos + 1);
    } else {
        schema = QStringLiteral("main");
        table = name;
    }
}

// QDuckdbResultPrivate 实现
QDuckdbResultPrivate::QDuckdbResultPrivate(QDuckdbResult *q, const QDuckdbDriver *db)
    : QSqlResultPrivate(q, db), stmt(nullptr),
      currentRow(-1), rowCount(-1), affectedRows(-1)
{
    // 初始化duckdb_result结构体
    result = duckdb_result();
}

QDuckdbResultPrivate::~QDuckdbResultPrivate()
{
    cleanup();
}

void QDuckdbResultPrivate::cleanup()
{
    duckdb_destroy_result(&result);
    result = duckdb_result();

    if (stmt) {
        duckdb_destroy_prepare(&stmt);
        stmt = nullptr;
    }
    
    currentRow = -1;
    rowCount = -1;
    affectedRows = -1;
}

// DuckDB结果记录构建方法
void QDuckdbResultPrivate::buildRecordFromResult()
{
    record.clear();
    
    if (duckdb_column_count(&result) == 0) {
        return;
    }

    // 获取列数
    int columnCount = duckdb_column_count(&result);
    
    // 遍历所有列
    for (int i = 0; i < columnCount; ++i) {
        // 获取列名
        const char* columnName = duckdb_column_name(&result, i);
        QString fieldName = QString::fromUtf8(columnName);
        
        // 获取列类型并映射到QVariant类型
        duckdb_type columnType = duckdb_column_type(&result, i);
        QMetaType::Type qtType = QMetaType::QString;
        
        switch (columnType) {
        case DUCKDB_TYPE_BOOLEAN:
            qtType = QMetaType::Bool;
            break;
        case DUCKDB_TYPE_TINYINT:
        case DUCKDB_TYPE_SMALLINT:
        case DUCKDB_TYPE_INTEGER:
            qtType = QMetaType::Int;
            break;
        case DUCKDB_TYPE_BIGINT:
            qtType = QMetaType::LongLong;
            break;
        case DUCKDB_TYPE_UTINYINT:
        case DUCKDB_TYPE_USMALLINT:
        case DUCKDB_TYPE_UINTEGER:
            qtType = QMetaType::UInt;
            break;
        case DUCKDB_TYPE_UBIGINT:
            qtType = QMetaType::ULongLong;
            break;
        case DUCKDB_TYPE_FLOAT:
            qtType = QMetaType::Double;
            break;
        case DUCKDB_TYPE_DOUBLE:
            qtType = QMetaType::Double;
            break;
        case DUCKDB_TYPE_DATE:
            qtType = QMetaType::QDate;
            break;
        case DUCKDB_TYPE_TIMESTAMP:
            qtType = QMetaType::QDateTime;
            break;
        case DUCKDB_TYPE_VARCHAR:
            qtType = QMetaType::QString;
            break;
        case DUCKDB_TYPE_BLOB:
            qtType = QMetaType::QByteArray;
            break;
        default:
            qtType = QMetaType::QString;
            break;
        }
        
        QSqlField field(fieldName, QMetaType(qtType));
        record.append(field);
    }
}

bool QDuckdbResultPrivate::prepare(const QString &query)
{
    cleanup();

    QByteArray utf8Query = query.toUtf8();
    
    // 使用DuckDB API准备语句
    duckdb_connection connection = drv_d_func()->conn;
    
    // 创建DuckDB预处理语句
    duckdb_state status = duckdb_prepare(connection, utf8Query.constData(), &stmt);
    if (status != DuckDBSuccess) {
        errorMessage = QStringLiteral("Failed to prepare DuckDB statement");
        printf(errorMessage.toUtf8().constData());
        return false;
    }
    return true;
}

bool QDuckdbResultPrivate::execute()
{
    if (!stmt) {
        errorMessage = QStringLiteral("No statement prepared");
        return false;
    }

    // 使用已经准备好的语句执行查询
    QString currentQuery = q_func()->lastQuery();
    duckdb_state status = duckdb_execute_prepared(stmt, &result);
    
    if (status != DuckDBSuccess) {
        errorMessage = QString::fromUtf8(duckdb_result_error(&result));
        return false;
    }

    // 处理结果集
    rowCount = duckdb_row_count(&result);
    //int columnCount = duckdb_column_count(&result);
    affectedRows = duckdb_rows_changed(&result);
    
    // 构建结果记录
    buildRecordFromResult();
    
    // 重置当前行指针
    currentRow = -1;

    return true;
}

bool QDuckdbResultPrivate::bindValue(int pos, const QVariant &val)
{
    if (!stmt || pos < 0) {
        return false;
    }

    int paramIdx = pos + 1; // DuckDB参数索引从1开始

    if (val.isNull()) {
        // 绑定NULL值
        duckdb_state status = duckdb_bind_null(stmt, paramIdx);
        return status == DuckDBSuccess;
    }

    switch (val.metaType().id()) {
    case QMetaType::Bool:
        {
            bool value = val.toBool();
            duckdb_state status = duckdb_bind_boolean(stmt, paramIdx, value);
            return status == DuckDBSuccess;
        }
    case QMetaType::Int:
        {
            int32_t value = val.toInt();
            duckdb_state status = duckdb_bind_int32(stmt, paramIdx, value);
            return status == DuckDBSuccess;
        }
    case QMetaType::LongLong:
        {
            int64_t value = val.toLongLong();
            duckdb_state status = duckdb_bind_int64(stmt, paramIdx, value);
            return status == DuckDBSuccess;
        }
    case QMetaType::UInt:
        {
            uint32_t value = val.toUInt();
            duckdb_state status = duckdb_bind_uint32(stmt, paramIdx, value);
            return status == DuckDBSuccess;
        }
    case QMetaType::ULongLong:
        {
            uint64_t value = val.toULongLong();
            duckdb_state status = duckdb_bind_uint64(stmt, paramIdx, value);
            return status == DuckDBSuccess;
        }
    case QMetaType::Double:
        {
            double value = val.toDouble();
            duckdb_state status = duckdb_bind_double(stmt, paramIdx, value);
            return status == DuckDBSuccess;
        }

    case QMetaType::QString:
        {
            QString str = val.toString();
            QByteArray utf8Str = str.toUtf8();
            duckdb_state status = duckdb_bind_varchar(stmt, paramIdx, utf8Str.constData());
            return status == DuckDBSuccess;
        }
    case QMetaType::QByteArray:
        {
            QByteArray data = val.toByteArray();
            duckdb_state status = duckdb_bind_blob(stmt, paramIdx, data.constData(), data.size());
            return status == DuckDBSuccess;
        }
    case QMetaType::QDate:
        {
            QDate date = val.toDate();
            if (!date.isValid()) {
                return duckdb_bind_null(stmt, paramIdx) == DuckDBSuccess;
            }
            duckdb_date ddate;
            duckdb_date_struct dstruct = duckdb_from_date(ddate);
            dstruct.year = date.year();
            dstruct.month = date.month();
            dstruct.day = date.day();
            ddate = duckdb_to_date(dstruct);
            duckdb_state status = duckdb_bind_date(stmt, paramIdx, ddate);
            return status == DuckDBSuccess;
        }
    case QMetaType::QDateTime:
        {
            QDateTime dt = val.toDateTime();
            if (!dt.isValid()) {
                return duckdb_bind_null(stmt, paramIdx) == DuckDBSuccess;
            }
            duckdb_timestamp timestamp;
            timestamp.micros = dt.toMSecsSinceEpoch() * 1000;
            duckdb_state status = duckdb_bind_timestamp(stmt, paramIdx, timestamp);
            return status == DuckDBSuccess;
        }
    default:
        {
            QString str = val.toString();
            QByteArray utf8Str = str.toUtf8();
            duckdb_state status = duckdb_bind_varchar(stmt, paramIdx, utf8Str.constData());
            return status == DuckDBSuccess;
        }
    }
}

QVariant QDuckdbResultPrivate::dataValue(int col)
{
    if (currentRow < 0 || col < 0 || col >= static_cast<int>(duckdb_column_count(&result))) {
        return QVariant();
    }

    // 检查是否为NULL值
    if (duckdb_value_is_null(&result, col, currentRow)) {
        return QVariant();
    }

    // 获取列类型
    duckdb_type columnType = duckdb_column_type(&result, col);
    
    // 从DuckDB结果中读取值
    switch (columnType) {
    case DUCKDB_TYPE_BOOLEAN:
        {
            bool value = duckdb_value_boolean(&result, col, currentRow);
            return QVariant(value);
        }
    case DUCKDB_TYPE_TINYINT:
        {
            int8_t value = duckdb_value_int8(&result, col, currentRow);
            return QVariant(static_cast<int>(value));
        }
    case DUCKDB_TYPE_SMALLINT:
        {
            int16_t value = duckdb_value_int16(&result, col, currentRow);
            return QVariant(static_cast<int>(value));
        }
    case DUCKDB_TYPE_INTEGER:
        {
            int32_t value = duckdb_value_int32(&result, col, currentRow);
            return QVariant(value);
        }
    case DUCKDB_TYPE_BIGINT:
        {
            int64_t value = duckdb_value_int64(&result, col, currentRow);
            return QVariant(static_cast<qlonglong>(value));
        }
    case DUCKDB_TYPE_UTINYINT:
        {
            uint8_t value = duckdb_value_uint8(&result, col, currentRow);
            return QVariant(static_cast<uint>(value));
        }
    case DUCKDB_TYPE_USMALLINT:
        {
            uint16_t value = duckdb_value_uint16(&result, col, currentRow);
            return QVariant(static_cast<uint>(value));
        }
    case DUCKDB_TYPE_UINTEGER:
        {
            uint32_t value = duckdb_value_uint32(&result, col, currentRow);
            return QVariant(value);
        }
    case DUCKDB_TYPE_UBIGINT:
        {
            uint64_t value = duckdb_value_uint64(&result, col, currentRow);
            return QVariant(static_cast<qulonglong>(value));
        }
    case DUCKDB_TYPE_FLOAT:
        {
            float value = duckdb_value_float(&result, col, currentRow);
            return QVariant(static_cast<double>(value));
        }
    case DUCKDB_TYPE_DOUBLE:
        {
            double value = duckdb_value_double(&result, col, currentRow);
            return QVariant(value);
        }
    case DUCKDB_TYPE_DATE:
        {
            duckdb_date value = duckdb_value_date(&result, col, currentRow);
            duckdb_date_struct dstruct = duckdb_from_date(value);
            QDate qdate(dstruct.year, dstruct.month, dstruct.day);
            return QVariant(qdate);
        }
    case DUCKDB_TYPE_TIMESTAMP:
        {
            duckdb_timestamp value = duckdb_value_timestamp(&result, col, currentRow);
            qint64 msecs = value.micros / 1000;
            QDateTime dt = QDateTime::fromMSecsSinceEpoch(msecs);
            return QVariant(dt);
        }
    case DUCKDB_TYPE_TIME:
        {
            duckdb_time value = duckdb_value_time(&result, col, currentRow);
            duckdb_time_struct tstruct = duckdb_from_time(value);
            QTime qtime(tstruct.hour, tstruct.min, tstruct.sec, tstruct.micros / 1000);
            return QVariant(qtime);
        }
    case DUCKDB_TYPE_VARCHAR:
        {
            duckdb_string value = duckdb_value_string(&result, col, currentRow);
            QString str = QString::fromUtf8(value.data, value.size);
            // 注释掉duckdb_free调用，避免双重释放
            // duckdb_free(value.data);
            return QVariant(str);
        }
    case DUCKDB_TYPE_BLOB:
        {
            duckdb_blob value = duckdb_value_blob(&result, col, currentRow);
            QByteArray data(static_cast<const char*>(value.data), value.size);
            // 注释掉duckdb_free调用，避免双重释放
            // duckdb_free(value.data);
            return QVariant(data);
        }
    case DUCKDB_TYPE_INTERVAL:
        {
            duckdb_interval value = duckdb_value_interval(&result, col, currentRow);
            QVariantMap interval;
            interval[QStringLiteral("months")] = value.months;
            interval[QStringLiteral("days")] = value.days;
            interval[QStringLiteral("micros")] = static_cast<qlonglong>(value.micros);
            return QVariant(interval);
        }
    default:
        {
            duckdb_string value = duckdb_value_string(&result, col, currentRow);
            QString str = QString::fromUtf8(value.data, value.size);
            // 注释掉duckdb_free调用，避免双重释放
            // duckdb_free(value.data);
            return QVariant(str);
        }
    }
}

bool QDuckdbResultPrivate::isValueNull(int col)
{
    if (currentRow < 0 || col < 0) {
        return true;
    }

    // 使用DuckDB API检查是否为NULL
    return duckdb_value_is_null(&result, col, currentRow);
}

QString QDuckdbResultPrivate::lastError() const
{
    return errorMessage;
}

QT_END_NAMESPACE